www.gusucode.com > VC++ SkinCtrls窗体常用控件换肤程序-源码程序 > VC++ SkinCtrls窗体常用控件换肤程序-源码程序/code/Shared/EnBitmap.cpp
// EnBitmap.cpp: implementation of the CEnBitmap class. // Download by http://www.NewXing.com ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "EnBitmap.h" #include <AFXPRIV.H> #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif const int HIMETRIC_INCH = 2540; enum { FT_BMP, FT_ICO, FT_JPG, FT_GIF, FT_UNKNOWN }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CEnBitmap::CEnBitmap() { } CEnBitmap::~CEnBitmap() { } BOOL CEnBitmap::LoadImage(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst, COLORREF crBack) { ASSERT(m_hObject == NULL); // only attach once, detach on destroy if (m_hObject != NULL) return FALSE; return Attach(LoadImageResource(uIDRes, szResourceType, hInst, crBack)); } BOOL CEnBitmap::LoadImage(LPCTSTR szImagePath, COLORREF crBack) { ASSERT(m_hObject == NULL); // only attach once, detach on destroy if (m_hObject != NULL) return FALSE; return Attach(LoadImageFile(szImagePath, crBack)); } HBITMAP CEnBitmap::LoadImageFile(LPCTSTR szImagePath, COLORREF crBack) { int nType = GetFileType(szImagePath); switch (nType) { // i suspect it is more efficient to load // bmps this way since it avoids creating device contexts etc that the // IPicture methods requires. that method however is still valuable // since it handles other image types and transparency case FT_BMP: return (HBITMAP)::LoadImage(NULL, szImagePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); case FT_UNKNOWN: return NULL; default: // all the rest { USES_CONVERSION; IPicture* pPicture = NULL; HBITMAP hbm = NULL; HRESULT hr = OleLoadPicturePath(T2OLE(szImagePath), NULL, 0, crBack, IID_IPicture, (LPVOID *)&pPicture); if (pPicture) { hbm = ExtractBitmap(pPicture, crBack); pPicture->Release(); } return hbm; } } return NULL; // can't get here } HBITMAP CEnBitmap::LoadImageResource(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst, COLORREF crBack) { BYTE* pBuff = NULL; int nSize = 0; HBITMAP hbm = NULL; // first call is to get buffer size if (GetResource(MAKEINTRESOURCE(uIDRes), szResourceType, hInst, 0, nSize)) { if (nSize > 0) { pBuff = new BYTE[nSize]; // this loads it if (GetResource(MAKEINTRESOURCE(uIDRes), szResourceType, hInst, pBuff, nSize)) { IPicture* pPicture = LoadFromBuffer(pBuff, nSize); if (pPicture) { hbm = ExtractBitmap(pPicture, crBack); pPicture->Release(); } } delete [] pBuff; } } return hbm; } IPicture* CEnBitmap::LoadFromBuffer(BYTE* pBuff, int nSize) { bool bResult = false; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize); void* pData = GlobalLock(hGlobal); memcpy(pData, pBuff, nSize); GlobalUnlock(hGlobal); IStream* pStream = NULL; IPicture* pPicture = NULL; if (CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK) { HRESULT hr = OleLoadPicture(pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&pPicture); pStream->Release(); } return pPicture; // caller releases } BOOL CEnBitmap::GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize) { HRSRC hResInfo; HANDLE hRes; LPSTR lpRes = NULL; int nLen = 0; bool bResult = FALSE; // Find the resource hResInfo = FindResource(hInst, lpName, lpType); if (hResInfo == NULL) return false; // Load the resource hRes = LoadResource(hInst, hResInfo); if (hRes == NULL) return false; // Lock the resource lpRes = (char*)LockResource(hRes); if (lpRes != NULL) { if (pResource == NULL) { nBufSize = SizeofResource(hInst, hResInfo); bResult = true; } else { if (nBufSize >= (int)SizeofResource(hInst, hResInfo)) { memcpy(pResource, lpRes, nBufSize); bResult = true; } } UnlockResource(hRes); } // Free the resource FreeResource(hRes); return bResult; } HBITMAP CEnBitmap::ExtractBitmap(IPicture* pPicture, COLORREF crBack) { ASSERT(pPicture); if (!pPicture) return NULL; CBitmap bmMem; CDC dcMem; CDC* pDC = CWnd::GetDesktopWindow()->GetDC(); if (dcMem.CreateCompatibleDC(pDC)) { long hmWidth; long hmHeight; pPicture->get_Width(&hmWidth); pPicture->get_Height(&hmHeight); int nWidth = MulDiv(hmWidth, pDC->GetDeviceCaps(LOGPIXELSX), HIMETRIC_INCH); int nHeight = MulDiv(hmHeight, pDC->GetDeviceCaps(LOGPIXELSY), HIMETRIC_INCH); if (bmMem.CreateCompatibleBitmap(pDC, nWidth, nHeight)) { CBitmap* pOldBM = dcMem.SelectObject(&bmMem); if (crBack != -1) dcMem.FillSolidRect(0, 0, nWidth, nHeight, crBack); HRESULT hr = pPicture->Render(dcMem, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, NULL); dcMem.SelectObject(pOldBM); } } CWnd::GetDesktopWindow()->ReleaseDC(pDC); return (HBITMAP)bmMem.Detach(); } int CEnBitmap::GetFileType(LPCTSTR szImagePath) { CString sPath(szImagePath); sPath.MakeUpper(); if (sPath.Find(".BMP") > 0) return FT_BMP; else if (sPath.Find(".ICO") > 0) return FT_ICO; else if (sPath.Find(".JPG") > 0 || sPath.Find(".JPEG") > 0) return FT_JPG; else if (sPath.Find(".GIF") > 0) return FT_GIF; // else return FT_UNKNOWN; }